package com.bort.system.serial;

import com.bort.system.common.DataContainer;
import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortDataListener;
import com.fazecast.jSerialComm.SerialPortEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;

@Component
public class SerialManager {

    Logger logger = LoggerFactory.getLogger(SerialManager.class);

    public SerialPort openingPort;

    @Bean
    void init(){
        if(portDiscovery()){
            portInitialize();
        }
    }

    public boolean portDiscovery(){
        List<SerialPort> ports = Arrays.asList(SerialPort.getCommPorts());
        for (SerialPort port : ports) {
            String desk = port.getDescriptivePortName();
            if(desk.contains("UART")){
                openingPort = port;
                return true;
            }
        }
        return false;
    }

    public void reconnect(){
        if (portDiscovery()){
            portInitialize();
        }
    }

    boolean portInitialize(){
        openingPort.setComPortParameters(9600, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY); // 设置端口参数
        /**
         你可以根据具体的需求选择适当的超时模式来控制串口通信的行为。在你的代码中，如果希望立即输出接收到的数据，可以选择 TIMEOUT_NONBLOCKING 模式。如果希望等待数据并确保完整读取，可以选择 TIMEOUT_READ_BLOCKING 模式。
         **/
        openingPort.setComPortTimeouts(SerialPort.TIMEOUT_NONBLOCKING, 0, 0);
        if (openingPort.openPort()) {
            System.out.println("Port opened successfully.");
        } else {
            System.out.println("Unable to open the port.");
            return false;
        }

        openingPort.addDataListener(new SerialPortDataListener() {
            @Override
            public int getListeningEvents() {
                return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
            }

            @Override
            public void serialEvent(SerialPortEvent serialPortEvent) {
                try {
                    if (serialPortEvent.getEventType() == SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
                        byte[] readBuffer = new byte[1024]; // 调整数组大小以适应预期的响应长度
                        int numRead = openingPort.readBytes(readBuffer, readBuffer.length);
                        if (numRead > 0) {
                            // 将读取的字节转换为十六进制字符串
                            StringBuilder data = new StringBuilder();
                            for (int i = 0; i < numRead; i++) {
                                data.append(String.format("%02X ", readBuffer[i]));
                            }
                            // 在这里进行收到数据的处理操作，例如加入阻塞队列，另一个模块消费队列解析收到的数据
                        }
                    } else if (serialPortEvent.getEventType() == SerialPort.FLOW_CONTROL_DISABLED) {
                        System.out.println("断开连接");
                    }
                    DataContainer.hearTime = System.currentTimeMillis()/1000;
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });

        return true;
    }

    public void sendMsg(String msg){
        if(openingPort != null){
            logger.info("[串口通信]-:{}",msg);
            if(openingPort.isOpen()){
                logger.info("[串口通信]-串口开通，即将发送消息:{}",msg);
                PrintWriter writer = new PrintWriter(openingPort.getOutputStream());
                writer.write(msg);
                writer.flush();
                writer.close();
                logger.info("[串口通信]-消息已发送:{}",msg);
            }
        }
    }

}
